//package com.cqrcb.cloud.config.aspect;
//
//import com.alibaba.fastjson.JSON;
//import com.cqrcb.cloud.config.annotation.CustomChain;
//import com.cqrcb.cloud.config.redis.annotation.CustomCachePut;
//import com.cqrcb.cloud.config.redis.annotation.CustomCacheable;
//import com.cqrcb.cloud.config.redis.constant.RedisTools;
//import com.cqrcb.cloud.config.redis.el.ELUtil;
//import com.cqrcb.cloud.config.redis.exception.LockException;
//import com.cqrcb.cloud.config.redis.template.RedisRepository;
//import lombok.extern.slf4j.Slf4j;
//import org.aspectj.lang.ProceedingJoinPoint;
//import org.aspectj.lang.annotation.Around;
//import org.aspectj.lang.annotation.Aspect;
//import org.aspectj.lang.reflect.MethodSignature;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.data.redis.RedisConnectionFailureException;
//import org.springframework.util.StringUtils;
//
//import java.lang.reflect.Method;
//import java.lang.reflect.Type;
//
///**
// * 分布式锁切面
// *
// * @author yangxueyong
// * @date 2021/06/01
// */
//@Slf4j
//@Aspect
//public class ChainAspect {
//
//
//    @Around("@within(chain) || @annotation(chain)")
//    public Object aroundLock(ProceedingJoinPoint point, CustomChain chain) throws Throwable {
////        AnnotationUtils.getA
//        if(!redisTools.getRedisAvailable()){
//            return point.proceed();
//        }
//        if (cache == null) {
//            // 获取类上的注解
//            cache = point.getTarget().getClass().getDeclaredAnnotation(CustomCachePut.class);
//        }
//        String cacheKey = cache.key();
//        String[] cacheValues = cache.value();
//        long ttl = cache.ttl();
//        //获取key
//        cacheKey = getCacheKey(point, cacheKey, cacheValues);
//        if(ttl <= 0) {
//            try {
//                ttl = redisRepository.getTtl(cacheKey);
//            }catch (RedisConnectionFailureException e){
//                redisTools.getAndSetRedisAvailable(false);
//                log.warn("未能获取到指定key的过期时间，key:{},错误:{}",cacheKey,e.getMessage());
//                return point.proceed();
//            }
//        }
//        //将方法执行结果存入redis
//        Object proceed = point.proceed();
//        try {
//            storeValueToRedis(proceed, cacheKey, ttl);
//        }catch (RedisConnectionFailureException e){
//            redisTools.getAndSetRedisAvailable(false);
//            log.warn("未能存入到redis，key:{},错误:{}",cacheKey,e.getMessage());
//        }
//        return proceed;
//    }
//
//
//    @Around("@within(cache) || @annotation(cache)")
//    public Object aroundLock(ProceedingJoinPoint point, CustomCacheable cache) throws Throwable {
//        if(!redisTools.getRedisAvailable()){
//            return point.proceed();
//        }
//        if (cache == null) {
//            // 获取类上的注解
//            cache = point.getTarget().getClass().getDeclaredAnnotation(CustomCacheable.class);
//        }
//        String cacheKey = cache.key();
//        String[] cacheValues = cache.value();
//        long ttl = cache.ttl();
//        //获取key
//        cacheKey = getCacheKey(point, cacheKey, cacheValues);
//        //类型转换，向下转型，必定成功，因为其内部的实现MethodSignatureImpl实现的就是MethodSignature接口
//        MethodSignature signature = (MethodSignature) point.getSignature();
//        //获取method对象
//        Method method = signature.getMethod();
//        Object obj = null;
//        try {
//            obj = redisRepository.get(cacheKey);
//        }catch (RedisConnectionFailureException e){
//            redisTools.getAndSetRedisAvailable(false);
//            log.warn("获取redis值出错->{}",e.getMessage());
//            return point.proceed();
//        }
//        if(obj != null){
//            String objStr = obj.toString().trim();
//            if(!"".equals(objStr) && !"null".equals(objStr) && !"[]".equals(objStr) && !"{}".equals(objStr)) {
//                Type genericReturnType = method.getGenericReturnType();
//                Object o = JSON.parseObject(obj.toString(), genericReturnType);
//                if (o != null ) {
//                    return o;
//                }
//            }
//        }
//
//        //将方法执行结果存入redis
//        Object proceed = point.proceed();
//        try {
//            storeValueToRedis(proceed, cacheKey, ttl);
//        }catch (RedisConnectionFailureException e){
//            redisTools.getAndSetRedisAvailable(false);
//            log.warn("存储到redis时出错->{}",e.getMessage());
//        }
//        return proceed;
//    }
//
//    /**
//     * 将数据存入redis
//     *
//     * @param proceed    点
//     * @param cacheKey 缓存键
//     * @param ttl      ttl
//     * @return {@link Object}
//     * @throws Throwable throwable
//     */
//    private Object storeValueToRedis(Object proceed, String cacheKey, long ttl) {
//        String objStr = JSON.toJSONString(proceed);
//        if (ttl > 0) {
//            redisRepository.setExpire(cacheKey, objStr, ttl);
//        } else {
//            redisRepository.set(cacheKey, objStr);
//        }
//        return proceed;
//    }
//
//    /**
//     * 获取缓存键
//     *
//     * @param point       点
//     * @param cacheKey    缓存键
//     * @param cacheValues 缓存值
//     * @return {@link String}
//     */
//    private String getCacheKey(ProceedingJoinPoint point, String cacheKey, String[] cacheValues) {
//        if (redisRepository == null) {
//            throw new LockException("redisRepository is null");
//        }
//        if (StringUtils.isEmpty(cacheKey)) {
//            throw new LockException("cacheKey is null");
//        }
//
//        if (cacheKey.contains("#")) {
//            MethodSignature methodSignature = (MethodSignature) point.getSignature();
//            //获取方法参数值
//            Object[] args = point.getArgs();
//            cacheKey = ELUtil.getValBySpEL(cacheKey, methodSignature, args);
//        }
//        if (!StringUtils.isEmpty(cacheKey)) {
//            String cacheValue = "";
//            if (cacheValues != null) {
//                cacheValue = cacheValues[0];
//            }
//            cacheKey = cacheValue + ":" + cacheKey;
//        }
//        return cacheKey;
//    }
//
//}
